

#include <myqueue.h>
#include <mythread.h>
#include <malloc.h>
#include <stdio.h>

int mythread_inq(mythread_queue_t *headp, void *item)
{
  mythread_queue_t old, q, head;

  head = *headp;

  if (head == NULL)
    return;

  q = head;
  do {
    if (q->item == item)
      return TRUE; /* found */
    q = q->next;
  } while (q != head);

  return FALSE; /* not found */
}

int mythread_lenq(mythread_queue_t *headp)
{
  mythread_queue_t old, q, head;
  int ret = 0;

  head = *headp;

  if (head == NULL)
    return ret;

  q = head;
  do {
    q = q->next;
    ret++;
  } while (q != head);

  return ret;
}

void mythread_q_init(mythread_queue_t *headp, void *item)
{
  mythread_queue_t new, head;

  new = (mythread_queue_t) malloc(sizeof(struct mythread_queue));
  if (new == NULL) {
    printf("malloc error\n");
    exit(1);
  }
  new->item = item;

  new->prev = new;
  new->next = new;

  *headp = new;
}

/**
 *  Enqueue the new item at the tail of any items at the same priority level 
 *
 *@param headp  Head of queue to enqueue item on
 *@param item  Thread to enqueue
 */
void mythread_enq(mythread_queue_t *headp, void *item)
{
  mythread_queue_t new, head, next, prev;

  if (*headp == NULL) {
    mythread_q_init(headp, item);
    return;
  }
  
  head = *headp;

  new = (mythread_queue_t) malloc(sizeof(struct mythread_queue));
  if (new == NULL) {
    printf("malloc error\n");
    exit(1);
  }
  new->item = item;
  
	int queueLen = mythread_lenq(headp);
	/*printf("queueLen is: %d\n", queueLen);*/

	mythread_queue_t queue = *headp;
	mythread_queue_t queueNext, queuePrev;

	mythread_t currentThread;
	mythread_t newThread = (mythread_t) item;
	/* printf("Enqueue: Priority of new thread is: %d\n", newThread->dprio); */
  
	int i;
	for(i = 0;i < queueLen;queue = queueNext){
		/* Go ahead and set next queue pointer */
		queueNext = queue->next;
		queuePrev = queue->prev;
			
		currentThread = (mythread_t) queue->item;
		
		/* printf("Enqueue: Priority of current thread is: %d\n", currentThread->dprio); */
		
		if((newThread->dprio < currentThread->dprio)){
			/* printf("SETTING HEAD EQUAL TO QUEUE!!!!\n"); */
			if(currentThread == ((mythread_t)(head->item))){
				*headp = new;
			}
			
			next = queue;
			prev = queuePrev;
		
			new->prev = prev;
			new->next = next;
			prev->next = new;
			next->prev = new;
			return;
		}
			
		i++;
	}
	
	next = head;
	prev = head->prev;

	new->prev = prev;
	new->next = next;
	prev->next = new;
	next->prev = new;
}

void mythread_deq(mythread_queue_t *headp, void *item)
{
  mythread_queue_t old, q, head;

  head = *headp;

  q = head;
  do {
    if (q->item == item) {
      old = q;
      old->next->prev = q->prev;
      old->prev->next = q->next;
      if (old == head) {
	if (old->next == old)
	  *headp = (mythread_queue_t) NULL;
	else
	  *headp = old->next;
      }
      free(old);
      return; /* found */
    }
    q = q->next;
  } while (q != head);

  /* not found */
}
